home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / functions.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  18.2 KB  |  723 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 15
  2. /* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
  3. #pragma load EUDORA_LOAD
  4. #pragma segment Misc
  5.  
  6. Boolean CloseRemaining(WindowPeek win);
  7. short ReallyChangePassword(UPtr user,UPtr host,UPtr old,UPtr new);
  8. short SendPwCommand(short cmd,UPtr arg);
  9. short CheckResult(UPtr buffer);
  10. /************************************************************************
  11.  * DoSendQueue - send queued messages, including setup
  12.  ************************************************************************/
  13. short DoSendQueue(void)
  14. {
  15.     short err=0;
  16. #ifdef POPSECURE
  17.     Str255 accnt;
  18.  
  19.     GetPref(accnt,PREF_POP);
  20.     if (!*Password && GetPassword(accnt,Password,sizeof(Password),ENTER))
  21.         return(1);
  22. #endif
  23.  
  24.     AlertsTimeout = PrefIsSet(PREF_AUTO_DISMISS);
  25.     OpenProgress();
  26. #ifdef POPSECURE
  27.     if (UseCTB && (!UUPCOut || !UUPCIn)) err=DialThePhone();
  28. #else
  29.     if (!UUPCOut && UseCTB) err=DialThePhone();
  30. #endif
  31.     if (!err) err=SendTheQueue();
  32.     if (UseCTB) HangUpThePhone();
  33.     CloseProgress();
  34.     AlertsTimeout = False;
  35.     SetSendQueue();
  36.     return(err);
  37. }
  38.  
  39. /************************************************************************
  40.  * SendTheQueue - send queued messages, assuming cnxn is setup
  41.  ************************************************************************/
  42. short SendTheQueue(void)
  43. {
  44.     TOCType **tocH=nil;
  45.     int sumNum = -1;
  46.     Str255 server;
  47.     int port;
  48.     MessType **messH;
  49.     Handle table;
  50.     short err,code=0;
  51.     short tableId;
  52.     long gmtSecs = GMTDateTime();
  53.     short defltTableId;
  54.     UPtr tablePtr=NuPtr(256);
  55.     short lastId = 0;
  56.     
  57.     defltTableId = GetRLong(PREF_STRN+PREF_OUT_XLATE);
  58.     if (!NewTables || defltTableId==DEFAULT_TABLE) defltTableId = TRANS_OUT_TABL;
  59.  
  60.     GetSMTPInfo(server);
  61.     port = GetRLong(SMTP_PORT);
  62.     
  63. #ifdef POPSECURE
  64.     if (!POPSecure && (err=VetPOP())) goto done;
  65. #endif
  66.     ComposeLogR(LOG_SEND,nil,START_SEND_LOG,server,port);
  67.     if (err=StartSMTP(server,port)) goto done;
  68.  
  69.     if (!(tocH=GetOutTOC())) goto done;
  70.  
  71.     if (!NewTables && !TransOut && (table=GetResource('taBL',TRANS_OUT_TABL)))
  72.     {
  73.         BlockMove(*table,tablePtr,256);
  74.         TransOut = tablePtr;
  75.         lastId = TRANS_OUT_TABL;
  76.     }
  77.     for (sumNum=0; sumNum<(*tocH)->count && code<600; sumNum++)
  78.         if ((*tocH)->sums[sumNum].state == QUEUED &&
  79.             (*tocH)->sums[sumNum].seconds<=gmtSecs)
  80.         {
  81.           TimeStamp(tocH,sumNum,0,0);
  82.             
  83.             /*
  84.              * ready a translation table, if needed
  85.              */
  86.             tableId = (*tocH)->sums[sumNum].tableId;
  87.             if (tableId==DEFAULT_TABLE) tableId=defltTableId;
  88.             if (tableId != lastId)
  89.             {
  90.                 if (tableId!=NO_TABLE && tablePtr && (table = GetResource('taBL',tableId)))
  91.                 {
  92.                     BlockMove(*table,tablePtr,256);
  93.                     TransOut = tablePtr;
  94.                     lastId = tableId;        /* so we don't have to fetch it next time */
  95.                 }
  96.                 else
  97.                     TransOut = nil;    /* no table */
  98.             }
  99.             
  100.             /*
  101.              * actually send the message
  102.              */
  103.             if (!(code=(UUPCOut ? UUPCSendMessage(tocH,sumNum) :
  104.                                                         SendMessage(tocH,sumNum))))
  105.             {
  106.                 messH = (*tocH)->sums[sumNum].messH;
  107.                 if (messH && (*messH)->win)
  108.                     CloseMyWindow((*messH)->win);
  109. #ifdef DEBUG
  110. if (BUG4)
  111. {
  112.     TimeStamp(tocH,sumNum,0,0);
  113. }
  114. else
  115. {
  116. #endif
  117.                 SetState(tocH,sumNum,SENT);
  118.                 if (((*tocH)->sums[sumNum].flags&FLAG_KEEP_COPY)==0)
  119.                 {
  120.                     DeleteMessage(tocH,sumNum);
  121.                     sumNum--;         /* back up, since we deleted the message */
  122.                 }
  123. #ifdef DEBUG
  124. }
  125. #endif
  126.             }
  127.             else if (code==550)
  128.                 (*tocH)->sums[sumNum].flags |= FLAG_ADDRERR;
  129.         }
  130. done:
  131.     if (tablePtr) DisposPtr(tablePtr);
  132.     TransOut = nil;
  133.     (void) EndSMTP();
  134.     if (tocH && (*tocH)->win && sumNum>=0)
  135.         BoxSelectAfter((*tocH)->win,sumNum);
  136.         
  137.     if (!AmQuitting && tocH)
  138.     {
  139.         SendQueue = 0;
  140.         for (sumNum=(*tocH)->count-1; sumNum>=0; sumNum--)
  141.         {
  142.             if ((*tocH)->sums[sumNum].flags&FLAG_ADDRERR)
  143.             {
  144.                 (*tocH)->sums[sumNum].flags &= ~FLAG_ADDRERR;
  145.                 if (!GetAMessage(tocH,sumNum,nil,True)) break;
  146.             }
  147.         }
  148.     }
  149.     SetSendQueue();
  150.     FlushTOCs(True,False);    /* save memory, in case Out and Trash are large,
  151.                                                          and we're going on to do a check */
  152.     return(err);
  153. }
  154.  
  155. /**********************************************************************
  156.  * DoQuit - let's get outta here
  157.  **********************************************************************/
  158. void DoQuit()
  159. {
  160.   uLong never = 3600*GetRLong(NEVER_WARN);
  161.     Str31 hours;
  162.     uLong now = GMTDateTime();
  163.     Boolean remember = !EjectBuckaroo;
  164.     
  165.     Done = EjectBuckaroo = False;
  166.     AmQuitting = True;
  167.     if (ForceSend > now && ForceSend - now < never)
  168.     {
  169.         GetRString(hours,NEVER_WARN);
  170.       switch (AlertStr(QUIT_MQ_ALRT,Stop,hours))
  171.         {
  172.           case QMQ_SEND_ALL:
  173.                 WarpQueue(0);
  174.                 DoSendQueue();
  175.                 break;
  176.             case QMQ_SEND:
  177.                 WarpQueue(never);
  178.               DoSendQueue();
  179.                 break;
  180.             case QMQ_DONT:
  181.               break;
  182.             default:
  183.                 AmQuitting = False;
  184.                 return;
  185.         }
  186.     }
  187.     if (SendQueue)
  188.     {
  189.         switch (ReallyDoAnAlert(QUIT_QUEUE_ALRT,Stop))
  190.         {
  191.             case QQL_SEND:
  192.                 DoSendQueue();
  193.                 break;
  194.             case QQL_QUIT:
  195.                 break;
  196.             default:
  197.                 AmQuitting = False;
  198.                 return;
  199.         }
  200.     }
  201.     if (remember) RememberOpenWindows();
  202.     if (!CloseAll()) {AmQuitting=False; return;}
  203.     
  204.     Done = True;
  205. }
  206.  
  207. /************************************************************************
  208.  * CloseAll - close all windows
  209.  ************************************************************************/
  210. Boolean CloseAll(void)
  211. {
  212.     if (!CloseAllMessages()) return(False);
  213.     if (!CloseAllBoxes()) return(False);
  214.     if (!CloseRemaining(FrontWindow())) return(False);
  215. }
  216.  
  217. /************************************************************************
  218.  * CloseRemaining - get rid of any other windows there might be
  219.  ************************************************************************/
  220. Boolean CloseRemaining(WindowPeek win)
  221. {
  222.     if (!win) return(True);
  223.     if (!CloseRemaining(win->nextWindow)) return(False);
  224.     if (IsMyWindow(win)) return(CloseMyWindow(win));
  225.     else if (win->windowKind==dialogKind)
  226.     {
  227.         NukeUndo(win);
  228.         DisposDialog(win);
  229.     }
  230.     return(True);
  231. }
  232.  
  233. /**********************************************************************
  234.  * DoAboutUIUCmail - put up the about box
  235.  **********************************************************************/
  236. void DoAboutUIUCmail()
  237. {
  238.     Str63 versionString;
  239.     Str255 partition;
  240.     VersRecHndl version;
  241.     
  242.     if (version = (VersRecHndl) GetResource('vers',1))
  243.     {
  244.         PCopy(versionString,(*version)->shortVersion+*(*version)->shortVersion+1);
  245.         ReleaseResource(version);
  246.     }
  247.     else
  248.         *versionString = 0;
  249.     
  250.     ComposeRString(partition,MEM_PARTITION,CurrentSize()/(1K),
  251.                                                 EstimatePartitionSize()/(1K));
  252.         
  253.     SetDAFont(GetFontID("\pPalatino"));
  254.     MyParamText(versionString,partition,"","");
  255.     (void) ReallyDoAnAlert(ABOUT_ALRT,Normal);
  256.     SetDAFont(0);
  257. }
  258.  
  259. /**********************************************************************
  260.  * NotImplemented - tell the user a feature is not implemented
  261.  **********************************************************************/
  262. void NotImplemented(void)
  263. {
  264.     DoAnAlert(Stop,"\pSorry, I'm (still) too stupid to do that.");
  265. }
  266.  
  267.  
  268. /**********************************************************************
  269.  * DoPageSetup - carry on the Page Setup dialog with the user
  270.  **********************************************************************/
  271. void DoPageSetup()
  272. {
  273.     short err;
  274.     
  275.     /*
  276.      * try to open the printer
  277.      */
  278.     PrOpen();
  279.     if (PrError())
  280.     {
  281.         WarnUser(NO_PRINTER,PrError());
  282.         return;
  283.     }
  284.     
  285.     /*
  286.      * make sure we have some sort of page setup record
  287.      */
  288.     if (PageSetup==nil) PageSetup = GetResource(PRINT_RTYPE,PRINT_CSOp);
  289.     if (PageSetup==nil)
  290.     {
  291.         PageSetup = NuHandle(sizeof(TPrint));
  292.         if (PageSetup==nil)
  293.         {
  294.             WarnUser(COULDNT_SETUP,MemError());
  295.             PrClose();
  296.             return;
  297.         }
  298.         PrintDefault(PageSetup);
  299.         
  300.         /*
  301.          * save it in our prefs file
  302.          */
  303.         if (err=SettingsHandle(PRINT_RTYPE,nil,PRINT_CSOp,PageSetup))
  304.             WarnUser(SAVE_SETUP,err);
  305.         else
  306.             UpdateResFile(SettingsRefN);
  307.     }
  308.  
  309.     /*
  310.      * let the user see it
  311.      */
  312.     PushCursor(arrowCursor);
  313.     if (PrStlDialog(PageSetup))
  314.     {
  315.         ChangedResource(PageSetup);                 /* save it in prefs file */
  316.         UpdateResFile(SettingsRefN);
  317.         if (ResError())
  318.             WarnUser(SAVE_SETUP,ResError());
  319.     }
  320.     PopCursor();
  321.     
  322.     /*
  323.      * done
  324.      */
  325.     PrClose();
  326. }
  327.  
  328. /************************************************************************
  329.  * DoComposeNew - start a new outgoing message
  330.  ************************************************************************/
  331. MyWindowPtr DoComposeNew(short toWhom)
  332. {
  333.     TOCType **tocH;
  334.     MSumType sum;
  335.     Byte buffer[1024];
  336.     long len;
  337.     short err;
  338.     MyWindowPtr newWin;
  339.     
  340.     if (!(tocH=GetOutTOC())) DieWithError(FATAL,1);
  341.     
  342.     CreateMessageBody(buffer);
  343.     len = strlen(buffer);
  344.     
  345.     WriteZero(&sum,sizeof(MSumType));
  346.     sum.offset = FindTOCSpot(tocH,len);
  347.     sum.length = len;
  348.     sum.state = UNSENDABLE;
  349.     sum.flags |= FLAG_NBK;
  350.     sum.flags |= FLAG_OUT;
  351.     sum.tableId = DEFAULT_TABLE;
  352.     if (PrefIsSet(PREF_WRAP_OUT)) sum.flags |= FLAG_WRAP_OUT;
  353.     if (PrefIsSet(PREF_SIG)) sum.flags |= FLAG_SIG;
  354.     if (PrefIsSet(PREF_BX_TEXT)) sum.flags |= FLAG_BX_TEXT;
  355.     if (PrefIsSet(PREF_KEEP_OUTGOING)) sum.flags |= FLAG_KEEP_COPY;
  356.     if (PrefIsSet(PREF_TAB_IN_TEXT)) sum.flags |= FLAG_TABS;
  357.  
  358.     sum.seconds = 0;
  359.     if (BoxFOpen(tocH)) return(nil);
  360.  
  361.     if (err=SetFPos((*tocH)->refN,fsFromStart,sum.offset))
  362.     {
  363.         FileSystemError(READ_MBOX,(*tocH)->name,err);
  364.         return(nil);
  365.     }
  366.     
  367.     if (err=FSWrite((*tocH)->refN,&len,buffer))
  368.     {
  369.         FileSystemError(WRITE_MBOX,(*tocH)->name,err);
  370.         return(nil);
  371.     }
  372.     (void) SetEOF((*tocH)->refN,sum.offset+len);
  373.     BoxFClose(tocH);
  374.     
  375.     SaveMessageSum(&sum,tocH);
  376.     
  377.     newWin = OpenComp(tocH,(*tocH)->count-1,nil,False);
  378.     if (newWin && toWhom)
  379.     {
  380.         MessHandle newMessH = (MessType **)newWin->qWindow.refCon;
  381.         MyGetItem(GetMHandle(NEW_TO_HIER_MENU),toWhom,buffer);
  382.         SetMessText(newMessH,TO_HEAD-1,buffer+1,*buffer);
  383.         (*newMessH)->win->isDirty = False;
  384.     }
  385.     return(newWin);
  386. }
  387.  
  388. /************************************************************************
  389.  * EmptyTrash - empty the trash mailbox
  390.  ************************************************************************/
  391. void EmptyTrash(void)
  392. {
  393.     Str63 name;
  394.                 Str15 suffix;
  395.     TOCType **tocH;
  396.     short refN;
  397.     
  398.     
  399.     GetRString(name,TRASH);
  400.  
  401.     /*
  402.      * open and truncate the mailbox
  403.      */
  404.     if (!FSHOpen(name,MyVRef,MyDirId,&refN,fsRdWrPerm))
  405.     {
  406.         SetEOF(refN,0);
  407.         FSClose(refN);
  408.     }
  409.  
  410.     tocH = FindTOC(MyDirId,name);
  411.     if (tocH && (*tocH)->win)
  412.     {
  413.         (*tocH)->count = 0;
  414.         (*tocH)->dirty = True;
  415.         SetHandleSize(tocH,sizeof(TOCType));
  416.         MyWindowMaxes((*tocH)->win,0,0);
  417.         MyWindowDidResize((*tocH)->win,nil);
  418.         InvalContent((*tocH)->win);
  419.     }
  420.     else
  421.     {
  422.         /*
  423.             * delete the toc
  424.             */
  425.         PCat(name,GetRString(suffix,TOC_SUFFIX));
  426.         HDelete(MyVRef,MyDirId,name);
  427.     }
  428.  
  429. }
  430.  
  431. /************************************************************************
  432.  * CloseAllBoxes
  433.  ************************************************************************/
  434. Boolean CloseAllBoxes(void)
  435. {
  436.     TOCType **thisTOC,**nextTOC;
  437.     
  438.     for (thisTOC=TOCList; thisTOC; thisTOC=nextTOC)
  439.     {
  440.         nextTOC = (*thisTOC)->next;
  441.         if (!CloseMyWindow((*thisTOC)->win)) return(False);
  442.     }
  443.     return(True);
  444. }
  445.  
  446. /************************************************************************
  447.  *
  448.  ************************************************************************/
  449. Boolean CloseAllMessages(void)
  450. {
  451.     MessType **thisMess, **nextMess;
  452.     
  453.     for (thisMess=MessList; thisMess; thisMess=nextMess)
  454.     {
  455.         nextMess = (*thisMess)->next;
  456.         if (!CloseMyWindow((*thisMess)->win)) return(False);
  457.     }
  458.     return(True);
  459. }
  460.  
  461.  
  462. /************************************************************************
  463.  * AddSelectionAsTo - add the current selection to the to list
  464.  ************************************************************************/
  465. void AddSelectionAsTo(void)
  466. {
  467.     MyWindowPtr win = FrontWindow();
  468.     Str63 scratch;
  469.     short len;
  470.     TEHandle teh = WinTEH(win);
  471.     
  472.     if (!teh) return;
  473.     
  474.     len = (*teh)->selEnd - (*teh)->selStart;
  475.     if (!len) return;
  476.     
  477.     if (len>sizeof(scratch)-1)
  478.     {
  479.         WarnUser(TO_TOO_LONG,len);
  480.         return;
  481.     }
  482.     
  483.     BlockMove(*(*teh)->hText+(*teh)->selStart,scratch+1,len);
  484.     *scratch = len;
  485.     AddStringAsTo(scratch);
  486. }
  487.  
  488. /************************************************************************
  489.  * AddStringAsTo - add a string to the to list
  490.  ************************************************************************/
  491. void AddStringAsTo(UPtr string)
  492.     short spot,result;
  493.     MenuHandle mh;
  494.     Str63 oldItem;
  495.     short menu;
  496.  
  497.     mh = GetMHandle(NEW_TO_HIER_MENU);
  498.     for (spot=1;spot<=CountMItems(mh);spot++)
  499.     {
  500.         MyGetItem(mh,spot,oldItem);
  501.         result = IUCompString(string,oldItem);
  502.         if (result==0) return;
  503.         if (result<0) break;
  504.     }
  505.     
  506.     for (menu=NEW_TO_HIER_MENU;menu<=INSERT_TO_HIER_MENU;menu++)
  507.         MyInsMenuItem(GetMHandle(menu),string,spot-1);
  508.     
  509.     ToMenusChanged();
  510. }
  511.  
  512. /************************************************************************
  513.  * ToMenusChanged - see that the to menus get written out
  514.  ************************************************************************/
  515. void ToMenusChanged(void)
  516. {
  517.     MenuHandle mh;
  518.     
  519.     mh = GetResource('MENU',NEW_TO_HIER_MENU+1000);
  520.     if (mh)
  521.     {
  522.         Handle savedProcId = (*mh)->menuProc;
  523.         (*mh)->menuProc = nil;
  524.         ChangedResource(mh);
  525.         WriteResource(mh);
  526.         (*mh)->menuProc = savedProcId;
  527.     }
  528. }
  529.  
  530. #pragma segment Balloon
  531. /************************************************************************
  532.  * HelpRect - show a standard help balloon
  533.  ************************************************************************/
  534. void HelpRect(Rect *tipRect,short resSelect,short percentRight)
  535. {
  536.     HMMessageRecord hmmr;
  537.     Point tip;
  538.     static short oldSelect=0;
  539.     
  540.     if (oldSelect==resSelect && HMIsBalloon()) return;
  541.     oldSelect = resSelect;
  542.     LocalToGlobal((Point*)tipRect);
  543.     LocalToGlobal((Point*)tipRect + 1);
  544.     tip.h = tipRect->left + (percentRight*(tipRect->right-tipRect->left))/100;
  545.     tip.v = (tipRect->bottom+tipRect->top)/2;
  546.     hmmr.u.hmmStringRes.hmmResID = (resSelect/200)*200;
  547.     hmmr.u.hmmStringRes.hmmIndex = resSelect%200;
  548.     hmmr.hmmHelpType = khmmStringRes;
  549.     HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,0);
  550. }
  551.  
  552. /************************************************************************
  553.  * HelpPict - show a help balloon with a pict in it
  554.  ************************************************************************/
  555. void HelpPict(Rect *tipRect,short resId,short percentRight)
  556. {
  557.     HMMessageRecord hmmr;
  558.     Point tip;
  559.     static short oldId=0;
  560.     
  561.     if (oldId==resId && HMIsBalloon()) return;
  562.     oldId = resId;
  563.     LocalToGlobal((Point*)tipRect);
  564.     LocalToGlobal((Point*)tipRect + 1);
  565.     tip.h = tipRect->left + (percentRight*(tipRect->right-tipRect->left))/100;
  566.     tip.v = (tipRect->bottom+tipRect->top)/2;
  567.     hmmr.u.hmmPict = resId;
  568.     hmmr.hmmHelpType = khmmPict;
  569.     HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,0);
  570. }
  571.  
  572. /************************************************************************
  573.  * HelpRectString - show a standard help balloon, but provide a string
  574.  *  instead of a resource id.
  575.  ************************************************************************/
  576. void HelpRectString(Rect *tipRect,UPtr string,short percentRight)
  577. {
  578.     HMMessageRecord hmmr;
  579.     Point tip;
  580.     
  581.     LocalToGlobal((Point*)tipRect);
  582.     LocalToGlobal((Point*)tipRect + 1);
  583.     tip.h = tipRect->left + (percentRight*(tipRect->right-tipRect->left))/100;
  584.     tip.v = (tipRect->bottom+tipRect->top)/2;
  585.     PCopy(hmmr.u.hmmString,string);
  586.     hmmr.hmmHelpType = khmmString;
  587.     HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,0);
  588. }
  589.  
  590. /************************************************************************
  591.  * DoHelp - do help for a window
  592.  ************************************************************************/
  593. void DoHelp(MyWindowPtr win)
  594. {
  595.     Point mouse;
  596.     GrafPtr oldPort;
  597.     
  598.     if (!win) return;
  599.     GetPort(&oldPort);
  600.     SetPort(win);
  601.     GetMouse(&mouse);
  602.     
  603.     if (PtInRect(mouse,&((GrafPtr)win)->portRect) && win->help)
  604.         (*win->help)(win,mouse);
  605.  
  606.     SetPort(oldPort);
  607. }
  608. #pragma segment Misc
  609.         
  610. /************************************************************************
  611.  * HandleWindowChoice - handle the user choosing a window menu item
  612.  ************************************************************************/
  613. void HandleWindowChoice(short item)
  614. {
  615.     MyWindowPtr win;
  616.     
  617.     for (win=FrontWindow();win;win=win->qWindow.nextWindow)
  618.         if (win->qWindow.visible && !--item)
  619.             SelectWindow(win);
  620. }
  621.  
  622.  
  623. /************************************************************************
  624.  * ChangePassword - change the user's password
  625.  ************************************************************************/
  626. short ChangePassword(void)
  627. {
  628.     Str31 user, old, new, candidate;
  629.     Str255 account;
  630.     short err;
  631.     
  632.     *Password = 0;            /* make the user reenter it */
  633.     POPSecure = 0;
  634.     GetPref(account,PREF_POP);
  635.     if (!(err=GetPassword(account,old,sizeof(old),ENTER)))
  636.     {
  637.         if (!(err=GetPassword(account,candidate,sizeof(candidate),NEW)) &&
  638.                 !(err=GetPassword(account,new,sizeof(new),VERIFY)))
  639.         {
  640.             if (!EqualString(candidate,new,True,True))
  641.             {
  642.                 WarnUser(PW_MISMATCH,0);
  643.                 err = 1;
  644.             }
  645.             else
  646.             {
  647.                 GetPOPInfo(user,account);
  648.                 PCopy(Password,old);
  649.                 err = ReallyChangePassword(user,account,old,new);
  650.             }
  651.         }
  652.     }
  653.     if (err) InvalidatePasswords(True,False);
  654.     return(err);
  655. }
  656.  
  657. /************************************************************************
  658.  * ReallyChangePassword - change the user's password, really
  659.  ************************************************************************/
  660. short ReallyChangePassword(UPtr user,UPtr host,UPtr old,UPtr new)
  661. {
  662.     enum {PW_USER=801,PW_PASS,PW_NEWPASS,PW_QUIT};
  663.     short err=1;
  664.     long port = GetRLong(PW_PORT);
  665.     Str255 buffer,junk;
  666.     
  667.     OpenProgress();
  668.     if (!UseCTB || !DialThePhone())
  669.         if (!ConnectTrans(host,port,False))
  670.         {
  671.             if (!CheckResult(buffer) &&
  672.                     !SendPwCommand(PW_USER,user) && !CheckResult(buffer) &&
  673.                     !SendPwCommand(PW_PASS,old) && !CheckResult(buffer) &&
  674.                     !SendPwCommand(PW_NEWPASS,new) && !CheckResult(buffer))
  675.             {
  676.                 err = 0;
  677.                 SilenceTrans(True);
  678.                 if (!SendPwCommand(PW_QUIT,"")) CheckResult(junk);
  679.                 PCopy(Password,new);
  680.                 POPSecure = True;
  681.             }
  682.         }
  683.     if (UseCTB) HangUpThePhone();
  684.     DestroyTrans();
  685.     CloseProgress();
  686.     if (!err) {SetAlertBeep(False);AlertStr(OK_ALRT,Normal,buffer);SetAlertBeep(True);}
  687.     return(err);
  688. }
  689.  
  690. /************************************************************************
  691.  * SendPwCommand - send a password command
  692.  ************************************************************************/
  693. short SendPwCommand(short cmd,UPtr arg)
  694. {
  695.     Str255 buffer;
  696.     ComposeRString(buffer,cmd,arg,NewLine);
  697.     return (SendTrans(1,buffer+1,*buffer));
  698. }
  699.  
  700. /************************************************************************
  701.  * CheckResult - did the command succeed?
  702.  ************************************************************************/
  703. short CheckResult(UPtr buffer)
  704. {
  705.     short err;
  706.     
  707.     do
  708.     {
  709.         err = GetReply(buffer+1,253,False);
  710.         *buffer = strlen(buffer+1);
  711.         if (err>=400 && err<600)
  712.         {
  713.             Str255 pwErr;
  714.             GetRString(pwErr,PW_ERROR);
  715.             MyParamText(pwErr,buffer,"","");
  716.             ReallyDoAnAlert(OK_ALRT,Stop);
  717.         }
  718.         else Progress(NoBar,buffer);
  719.     }
  720.     while (err<200);
  721.     return(err>399);
  722. }